home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP05.ZIP / CHAP05 / PATRON / DOCUMENT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-07  |  12.5 KB  |  614 lines

  1. /*
  2.  * DOCUMENT.CPP
  3.  * Modifications for Chapter 5
  4.  *
  5.  * Implementation of the CPatronDoc derivation of CDocument that
  6.  * manages pages for us.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include <memory.h>
  19. #include "patron.h"
  20.  
  21.  
  22.  
  23. /*
  24.  * CPatronDoc::CPatronDoc
  25.  * CPatronDoc::~CPatronDoc
  26.  *
  27.  * Constructor Parameters:
  28.  *  hInst           HINSTANCE of the application.
  29.  */
  30.  
  31. CPatronDoc::CPatronDoc(HINSTANCE hInst)
  32.     : CDocument(hInst)
  33.     {
  34.     m_pPG=NULL;
  35.     m_lVer=VERSIONCURRENT;
  36.     //CHAPTER5MOD
  37.     m_pIStorage=NULL;
  38.     //End CHAPTER5MOD
  39.     return;
  40.     }
  41.  
  42.  
  43. CPatronDoc::~CPatronDoc(void)
  44.     {
  45.     if (NULL!=m_pPG)
  46.         delete m_pPG;
  47.  
  48.     //CHAPTER5MOD
  49.     if (NULL!=m_pIStorage)
  50.         m_pIStorage->Release();
  51.  
  52.     CoFreeUnusedLibraries();
  53.     //End CHAPTER5MOD
  54.  
  55.     return;
  56.     }
  57.  
  58.  
  59.  
  60.  
  61.  
  62. /*
  63.  * CPatronDoc::FInit
  64.  *
  65.  * Purpose:
  66.  *  Initializes an already created document window.  The client actually
  67.  *  creates the window for us, then passes that here for further
  68.  *  initialization.
  69.  *
  70.  * Parameters:
  71.  *  pDI             LPDOCUMENTINIT containing initialization parameters.
  72.  *
  73.  * Return Value:
  74.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  75.  */
  76.  
  77. BOOL CPatronDoc::FInit(LPDOCUMENTINIT pDI)
  78.     {
  79.     //Change the stringtable range to our customization.
  80.     pDI->idsMin=IDS_DOCUMENTMIN;
  81.     pDI->idsMax=IDS_DOCUMENTMAX;
  82.  
  83.     //Do default initialization
  84.     if (!CDocument::FInit(pDI))
  85.         return FALSE;
  86.  
  87.     //Pages are created when we get a ::ULoad later.
  88.     return TRUE;
  89.     }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96. /*
  97.  * CPatronDoc::FMessageHook
  98.  *
  99.  * Purpose:
  100.  *  Processes WM_SIZE for the document so we can resize the Pages window.
  101.  *
  102.  * Parameters:
  103.  *  <WndProc Parameters>
  104.  *  pLRes           LRESULT FAR * in which to store the return value
  105.  *                  for the message.
  106.  *
  107.  * Return Value:
  108.  *  BOOL            TRUE to prevent further processing, FALSE otherwise.
  109.  */
  110.  
  111. BOOL CPatronDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  112.     , LPARAM lParam, LRESULT FAR *pLRes)
  113.     {
  114.     UINT        dx, dy;
  115.     RECT        rc;
  116.  
  117.     if (WM_SIZE==iMsg && NULL!=m_pPG)
  118.         {
  119.         dx=LOWORD(lParam);
  120.         dy=HIWORD(lParam);
  121.  
  122.         //Resize the Pages window to fit the new client area of the document
  123.         GetClientRect(hWnd, &rc);
  124.         m_pPG->RectSet(&rc, FALSE);
  125.         }
  126.  
  127.     /*
  128.      * We return FALSE even on WM_SIZE so we can let the default procedure
  129.      * handle maximized MDI child windows appropriately.
  130.      */
  131.     return FALSE;
  132.     }
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141. /*
  142.  * CPatronDoc::Clear
  143.  *
  144.  * Purpose:
  145.  *  Sets all contents in the document back to defaults with no filename.
  146.  *
  147.  * Paramters:
  148.  *  None
  149.  *
  150.  * Return Value:
  151.  *  None
  152.  */
  153.  
  154. void CPatronDoc::Clear(void)
  155.     {
  156.     //Completely reset the pages
  157.     //CHAPTER5MOD
  158.     m_pPG->FIStorageSet(NULL, FALSE, FALSE);
  159.     //End CHAPTER5MOD
  160.  
  161.     CDocument::Clear();
  162.     m_lVer=VERSIONCURRENT;
  163.     return;
  164.     }
  165.  
  166.  
  167.  
  168.  
  169.  
  170. /*
  171.  * CPatronDoc::ULoad
  172.  *
  173.  * Purpose:
  174.  *  Loads a given document without any user interface overwriting the
  175.  *  previous contents of the editor.
  176.  *
  177.  * Parameters:
  178.  *  fChangeFile     BOOL indicating if we're to update the window title
  179.  *                  and the filename from using this file.
  180.  *  pszFile         LPSTR to the filename to load.  Could be NULL for
  181.  *                  an untitled document.
  182.  *
  183.  * Return Value:
  184.  *  UINT            An error value from DOCERR_*
  185.  */
  186.  
  187.  
  188. UINT CPatronDoc::ULoad(BOOL fChangeFile, LPSTR pszFile)
  189.     {
  190.     RECT        rc;
  191.     //CHAPTER5MOD
  192.     LPSTORAGE   pIStorage;
  193.     HRESULT     hr;
  194.     CLSID       clsID;
  195.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  196.  
  197.     if (NULL==pszFile)
  198.         {
  199.         //Create a new temp file.
  200.         hr=StgCreateDocfile(NULL, dwMode | STGM_CREATE | STGM_DELETEONRELEASE
  201.             , 0, &pIStorage);
  202.  
  203.         //Mark this as one of our class since we check with ReadClassStg below.
  204.         if (SUCCEEDED(hr))
  205.             WriteClassStg(pIStorage, CLSID_PatronPages);
  206.         }
  207.     else
  208.         {
  209.         hr=StgOpenStorage(pszFile, NULL, dwMode, NULL, 0, &pIStorage);
  210.         }
  211.  
  212.     if (FAILED(hr))
  213.         return DOCERR_COULDNOTOPEN;
  214.  
  215.     //Check if this is our type of file and exit if not.
  216.     hr=ReadClassStg(pIStorage, &clsID);
  217.  
  218.     if (FAILED(hr) || !IsEqualCLSID(clsID, CLSID_PatronPages))
  219.         {
  220.         pIStorage->Release();
  221.         return DOCERR_READFAILURE;
  222.         }
  223.  
  224.     //End CHAPTER5MOD
  225.  
  226.     //Attempt to create our contained Pages window.
  227.     m_pPG=new CPages(m_hInst);
  228.     GetClientRect(m_hWnd, &rc);
  229.  
  230.     //CHAPTER5MOD
  231.     if (!m_pPG->FInit(m_hWnd, &rc, WS_CHILD | WS_VISIBLE, ID_PAGES, NULL))
  232.         {
  233.         pIStorage->Release();
  234.         return DOCERR_READFAILURE;
  235.         }
  236.  
  237.     if (!m_pPG->FIStorageSet(pIStorage, FALSE, (BOOL)(NULL==pszFile)))
  238.         {
  239.         pIStorage->Release();
  240.         return DOCERR_READFAILURE;
  241.         }
  242.  
  243.     m_pIStorage=pIStorage;
  244.     Rename(pszFile);
  245.  
  246.     //Do initial setup if this is a new file, otherwise Pages handles things.
  247.     if (NULL==pszFile)
  248.         {
  249.         //Go initialize the Pages for the default printer.
  250.         if (!PrinterSetup(NULL, TRUE))
  251.             return DOCERR_COULDNOTOPEN;
  252.  
  253.         //Go create an initial page.
  254.         m_pPG->PageInsert(0);
  255.         }
  256.     //End CHAPTER5MOD
  257.  
  258.     FDirtySet(FALSE);
  259.     return DOCERR_NONE;
  260.     }
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267. //CHAPTER5MOD
  268. /*
  269.  * CPatronDoc::USave
  270.  *
  271.  * Purpose:
  272.  *  Writes the file to a known filename, requiring that the user has
  273.  *  previously used FileOpen or FileSaveAs in order to have a filename.
  274.  *
  275.  * Parameters:
  276.  *  uType           UINT indicating the type of file the user requested
  277.  *                  to save in the File Save As dialog.
  278.  *  pszFile         LPSTR under which to save.  If NULL, use the current name.
  279.  *
  280.  * Return Value:
  281.  *  UINT            An error value from DOCERR_*
  282.  */
  283.  
  284. UINT CPatronDoc::USave(UINT uType, LPSTR pszFile)
  285.     {
  286.     HRESULT     hr;
  287.     LPSTORAGE   pIStorage;
  288.  
  289.     //Save or Save As with the same file is just a commit.
  290.     if (NULL==pszFile || (NULL!=pszFile && 0==lstrcmpi(pszFile, m_szFile)))
  291.         {
  292.         WriteFmtUserTypeStg(m_pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
  293.  
  294.         //Insure pages are up to date.
  295.         m_pPG->FIStorageUpdate(FALSE);
  296.  
  297.         //Commit everyting
  298.         m_pIStorage->Commit(STGC_ONLYIFCURRENT);
  299.  
  300.         FDirtySet(FALSE);
  301.         return DOCERR_NONE;
  302.         }
  303.  
  304.     /*
  305.      * When we're given a name, open the storage, creating it new if
  306.      * it does not exist or overwriting the old one.  Then ::CopyTo
  307.      * from the current to the new, ::Commit the new, then ::Release
  308.      * the old.
  309.      */
  310.  
  311.     hr=StgCreateDocfile(pszFile, STGM_TRANSACTED | STGM_READWRITE
  312.         | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  313.  
  314.     if (FAILED(hr))
  315.         return DOCERR_COULDNOTOPEN;
  316.  
  317.     WriteClassStg(pIStorage, CLSID_PatronPages);
  318.     WriteFmtUserTypeStg(pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
  319.  
  320.     //Insure all pages are up-to-date.
  321.     m_pPG->FIStorageUpdate(TRUE);
  322.  
  323.     //This also copies the CLSID we stuff in here on file creation.
  324.     hr=m_pIStorage->CopyTo(NULL, NULL, NULL, pIStorage);
  325.  
  326.     if (FAILED(hr))
  327.         {
  328.         pIStorage->Release();
  329.         return DOCERR_WRITEFAILURE;
  330.         }
  331.  
  332.     pIStorage->Commit(STGC_ONLYIFCURRENT);
  333.  
  334.     /*
  335.      * Revert changes on the original storage.  If this was a temp file,
  336.      * it's deleted since we used STGM_DELETEONRELEASE.
  337.      */
  338.     m_pIStorage->Release();
  339.  
  340.     //Make this new storage current
  341.     m_pIStorage=pIStorage;
  342.     m_pPG->FIStorageSet(pIStorage, TRUE, FALSE);
  343.  
  344.     FDirtySet(FALSE);
  345.     Rename(pszFile);    //Update caption bar.
  346.  
  347.     return DOCERR_NONE;
  348.     }
  349. //End CHAPTER5MOD
  350.  
  351.  
  352.  
  353.  
  354.  
  355. /*
  356.  * CPatronDoc::Print
  357.  *
  358.  * Purpose:
  359.  *  Prints the current document.
  360.  *
  361.  * Parameters:
  362.  *  hWndFrame       HWND of the frame to use for dialog parents.
  363.  *
  364.  * Return Value:
  365.  *  BOOL            TRUE if printing happened, FALSE if it didn't start
  366.  *                  or didn't complete.
  367.  */
  368.  
  369. BOOL CPatronDoc::Print(HWND hWndFrame)
  370.     {
  371.     PRINTDLG        pd;
  372.     BOOL            fSuccess;
  373.  
  374.     memset(&pd, 0, sizeof(PRINTDLG));
  375.     pd.lStructSize=sizeof(PRINTDLG);
  376.     pd.hwndOwner  =hWndFrame;
  377.     pd.nCopies    =1;
  378.     pd.nFromPage  =-1;
  379.     pd.nToPage    =-1;
  380.     pd.nMinPage   =1;
  381.     pd.nMaxPage   =m_pPG->NumPagesGet();
  382.  
  383.     //Get the current document printer settings
  384.     pd.hDevMode=m_pPG->DevModeGet();
  385.  
  386.     pd.Flags=PD_RETURNDC | PD_ALLPAGES | PD_COLLATE
  387.         | PD_HIDEPRINTTOFILE | PD_NOSELECTION;
  388.  
  389.     if (!PrintDlg(&pd))
  390.         return FALSE;
  391.  
  392.     //Make sure the Pages knows about any printer changes.
  393.     if (!m_pPG->DevModeSet(pd.hDevMode, pd.hDevNames))
  394.         {
  395.         GlobalFree(pd.hDevMode);
  396.         GlobalFree(pd.hDevNames);
  397.         return FALSE;
  398.         }
  399.  
  400.     //Go do the actual printing.
  401.     fSuccess=m_pPG->Print(pd.hDC, PSZ(IDS_DOCUMENTNAME), pd.Flags
  402.         , pd.nFromPage, pd.nToPage, pd.nCopies);
  403.  
  404.     if (!fSuccess)
  405.         MessageBox(m_hWnd, PSZ(IDS_PRINTERROR), PSZ(IDS_DOCUMENTCAPTION), MB_OK);
  406.  
  407.     return fSuccess;
  408.     }
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415. /*
  416.  * CPatronDoc::PrinterSetup
  417.  *
  418.  * Purpose:
  419.  *  Selects a new printer and options for this document.
  420.  *
  421.  * Parameters:
  422.  *  hWndFrame       HWND of the frame to use for dialog parents.
  423.  *  fDefault        BOOL to avoid any dialog and just use the default.
  424.  *
  425.  * Return Value:
  426.  *  UINT            Undefined
  427.  *
  428.  */
  429.  
  430. UINT CPatronDoc::PrinterSetup(HWND hWndFrame, BOOL fDefault)
  431.     {
  432.     PRINTDLG        pd;
  433.  
  434.     //Attempt to get printer metrics for the default printer.
  435.     memset(&pd, 0, sizeof(PRINTDLG));
  436.     pd.lStructSize=sizeof(PRINTDLG);
  437.  
  438.     if (fDefault)
  439.         pd.Flags=PD_RETURNDEFAULT;
  440.     else
  441.         {
  442.         pd.hwndOwner=hWndFrame;
  443.         pd.Flags=PD_PRINTSETUP;
  444.  
  445.         //Get the current document printer settings
  446.         pd.hDevMode=m_pPG->DevModeGet();
  447.         }
  448.  
  449.     if (!PrintDlg(&pd))
  450.         return FALSE;
  451.  
  452.     if (!m_pPG->DevModeSet(pd.hDevMode, pd.hDevNames))
  453.         {
  454.         GlobalFree(pd.hDevNames);
  455.         GlobalFree(pd.hDevMode);
  456.         return FALSE;
  457.         }
  458.  
  459.     FDirtySet(TRUE);
  460.     return 1;
  461.     }
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469. /*
  470.  * CPatronDoc::NewPage
  471.  *
  472.  * Purpose:
  473.  *  Creates a new page in the document's pages control after the
  474.  *  current page.
  475.  *
  476.  * Parameters:
  477.  *  None
  478.  *
  479.  * Return Value:
  480.  *  UINT            Index of the new page.
  481.  */
  482.  
  483. UINT CPatronDoc::NewPage(void)
  484.     {
  485.     FDirtySet(TRUE);
  486.     return m_pPG->PageInsert(0);
  487.     }
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495. /*
  496.  * CPatronDoc::DeletePage
  497.  *
  498.  * Purpose:
  499.  *  Deletes the current page from the document.
  500.  *
  501.  * Parameters:
  502.  *  None
  503.  *
  504.  * Return Value:
  505.  *  UINT            Index of the now current page.
  506.  */
  507.  
  508. UINT CPatronDoc::DeletePage(void)
  509.     {
  510.     FDirtySet(TRUE);
  511.     return m_pPG->PageDelete(0);
  512.     }
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520. /*
  521.  * CPatronDoc::NextPage
  522.  *
  523.  * Purpose:
  524.  *  Shows the next page in the pages window.
  525.  *
  526.  * Parameters:
  527.  *  None
  528.  *
  529.  * Return Value:
  530.  *  UINT            Index of the new page.
  531.  */
  532.  
  533. UINT CPatronDoc::NextPage(void)
  534.     {
  535.     UINT        iPage;
  536.  
  537.     iPage=m_pPG->CurPageGet();
  538.     return m_pPG->CurPageSet(++iPage);
  539.     }
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547. /*
  548.  * CPatronDoc::PreviousPage
  549.  *
  550.  * Purpose:
  551.  *  Shows the previous page in the pages window.
  552.  *
  553.  * Parameters:
  554.  *  None
  555.  *
  556.  * Return Value:
  557.  *  UINT            Index of the new page.
  558.  */
  559.  
  560. UINT CPatronDoc::PreviousPage(void)
  561.     {
  562.     UINT        iPage;
  563.  
  564.     //If iPage is zero, then we wrap around to the end.
  565.     iPage=m_pPG->CurPageGet();
  566.     return m_pPG->CurPageSet(--iPage);
  567.     }
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574. /*
  575.  * CPatronDoc::FirstPage
  576.  *
  577.  * Purpose:
  578.  *  Shows the first page page in the pages window.
  579.  *
  580.  * Parameters:
  581.  *  None
  582.  *
  583.  * Return Value:
  584.  *  UINT            Index of the new page.
  585.  */
  586.  
  587. UINT CPatronDoc::FirstPage(void)
  588.     {
  589.     return m_pPG->CurPageSet(0);
  590.     }
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597. /*
  598.  * CPatronDoc::LastPage
  599.  *
  600.  * Purpose:
  601.  *  Shows the last page in the pages window.
  602.  *
  603.  * Parameters:
  604.  *  None
  605.  *
  606.  * Return Value:
  607.  *  UINT            Index of the last page.
  608.  */
  609.  
  610. UINT CPatronDoc::LastPage(void)
  611.     {
  612.     return m_pPG->CurPageSet(-1);
  613.     }
  614.